package com.yunhoo.contract.bean;

import com.yunhoo.base.model.ContractType;
import com.yunhoo.base.db.impl.PartnerImpl;
import com.yunhoo.base.model.Partner;
import com.yunhoo.base.model.Project;
import com.yunhoo.checkFlow.db.impl.CheckFlowImpl;
import com.yunhoo.contract.db.impl.*;
import com.yunhoo.contract.model.*;
import com.yunhoo.cqq.util.FileUploadDownloadToolKit;
import com.yunhoo.sys.util.common.*;
import com.yunhoo.sys.util.tree.TreeUtil;
import java.io.Serializable;
import java.util.*;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import org.richfaces.event.TreeSelectionChangeEvent;

@ManagedBean(name = "supplyContractBean")
@SessionScoped
public class SupplyContractBean implements Serializable {

    private String mainNumber = "";//主合同编号
    private MainInformation mainInfo = new MainInformation();//合同基本信息
    private DataModel<ContractContent> contentModel = new ListDataModel<ContractContent>();//合同内容
    private DataModel<ContractItem> itemModel = new ListDataModel<ContractItem>();//合同条款
    private DataModel<PayInformation> payInfoModel = new ListDataModel<PayInformation>();//付款信息
    private DataModel<Matter> matterModel = new ListDataModel<Matter>();//其他事项
    private DataModel<Duty> dutyModel = new ListDataModel<Duty>();//违约责任
    //
    private Integer contentRowIndex = -1;
    //
    private boolean addOrUpdate = false;//合同基本信息 控制
    private boolean editStatus = false;//合同基本信息 控制
    private double enough = 0;//付款信息合同余额
    //
    //private DataModel<ContractType> typeModel = null;//合同类型
    private DataModel<Partner> partnerModel = null;//供应商
    private List<MainInformation> mainList = null;//主合同列表
    //附件部分
    private Double docRemainSize = -1d;//还可上传 的 附件 大小总和（B）
    private Integer docRemainAmount = -1;//还可上传 的 附件 个数
    private List<ContractDocument> curDocList = null;

    public void init(String number) {
        mainNumber = ContractImpl.queryMainContractBySuplyContractNumber(number).getNumber();
        mainInfo = ContractImpl.queryMainInfoByNumber(number);
        contentModel.setWrappedData(ContractImpl.queryContractContentList(number));
        itemModel.setWrappedData(ContractImpl.queryContractItemList(number));
        payInfoModel.setWrappedData(ContractImpl.queryPayInformationList(number));
        matterModel.setWrappedData(ContractImpl.queryMatterList(number));
        dutyModel.setWrappedData(ContractImpl.queryDutyList(number));
    }

    //合同 编制部分
    private void initPartnerli() {
        List<Partner> partnerlist = PartnerImpl.selePartnerList();
        partnerModel.setWrappedData(partnerlist);
    }

    public void partnerliSelected() {
        mainInfo.setPartner(partnerModel.getRowData());//
        if (mainInfo.getIsPayCon() == 1) {//1:付款合同 --> 甲方自己（手填），乙方从partner中选择
            mainInfo.setNameB(mainInfo.getPartner().getName());
            mainInfo.setNameBstand(mainInfo.getPartner().getLegalPerson());

        } else if (mainInfo.getIsPayCon() == 0) {//0：收款合同 --> 乙方是自己（手填），甲方从partner中选择
            mainInfo.setNameA(mainInfo.getPartner().getName());
            mainInfo.setNameAstand(mainInfo.getPartner().getLegalPerson());
        }
    }

//    private void initContractTypeli() {
//        List<ContractType> typelist = ContractTypeImpl.seleTypelist();
//        typeModel.setWrappedData(typelist);
//    }
    public void inventSelected(String code, String name) {
        List<ContractContent> contentli = (ArrayList) contentModel.getWrappedData();
        if (contentRowIndex != -1) {
            contentli.get(contentRowIndex).setCode(code);
            contentli.get(contentRowIndex).setName(name);
        }
    }
//
//    public void contractTypeSelected() {
//        ContractType type = typeModel.getRowData();
//        mainInfo.setContractTypeCode(type.getCode());
//        mainInfo.setContractTypeName(type.getName());
//    }

    public void contractTypeTreeSelected(TreeSelectionChangeEvent event) {
        ContractType temp = (ContractType) TreeUtil.listener(event);
        if (temp.getIsEnd() == 1) {
            mainInfo.setContractTypeCode(temp.getCode());
            mainInfo.setContractTypeName(temp.getName());
            mainInfo.setIsPayCon(temp.getIsPayCon());
        }
    }

    public void projectTreeSelected(TreeSelectionChangeEvent event) {
        Project temp = (Project) TreeUtil.listener(event);
        if (temp.getIsEnd() == 1) {
            mainInfo.setProjCode(temp.getCode());
            mainInfo.setProjName(temp.getName());
        }
    }

    public void uploadDoc() {
        docParamInit();
    }

    public void showDoc() {
        System.out.println(" * * * " + "showDoc" + "  * * * ");
        curDocList = ContractImpl.queryDocList(mainInfo.getNumber());
    }

    public void deleteDoc(Integer docId) {
        boolean ok = ContractImpl.deleteDoc(mainInfo.getNumber(), docId);
        curDocList = ContractImpl.queryDocList(mainInfo.getNumber());
    }

    public void downloadDoc(ContractDocument row) {
        ContractDocument doc = row;
        String fileName = doc.getUrl();
        int dirLen = doc.getUrl().lastIndexOf("\\");
        fileName = fileName.substring(0, dirLen) + "\\" + doc.getDescription();
        FileUploadDownloadToolKit.download(fileName);
    }

    private void docParamInit() {
        Map map = SysConfigMap.getSysConfigMap("doc_ht");
        Integer maxSize = Integer.parseInt((String) map.get("maxSize"));//允许上传的附件大小总和（MB）
        Integer maxAmount = Integer.parseInt((String) map.get("maxAmount"));//允许上传的附件总数

        Integer curDocAmount = 0;
        Double curDocSize = 0d;

        List<ContractDocument> docList = ContractImpl.queryDocList(mainInfo.getNumber());
        if (docList != null) {

            curDocAmount = docList.size();

            for (ContractDocument doc : docList) {
                String size = doc.getDocSize().trim();
                int it = 0;
                Double sizeValue = 0d;
                if (size.endsWith("MB")) {
                    sizeValue = Double.parseDouble(size.substring(0, size.length() - 2));
                    it = 1000000;
                } else if (size.endsWith("KB")) {
                    sizeValue = Double.parseDouble(size.substring(0, size.length() - 2));
                    it = 1000;
                } else if (size.endsWith("B")) {
                    sizeValue = Double.parseDouble(size.substring(0, size.length() - 1));
                    it = 1;
                }
                curDocSize += it * sizeValue;
            }
        }

        docRemainSize = maxSize * 1024000 - curDocSize;
        docRemainAmount = maxAmount - curDocAmount;

        FileUploadBean fileUploadBean = (FileUploadBean) FacesUtils.getManagedBean("fileUploadBean");
        fileUploadBean.initParam(docRemainAmount, docRemainSize);

        System.out.println(" * * * " + "docRemaiSize : " + docRemainSize + "  * * * ");
        System.out.println(" * * * " + "docRemainAmount: " + docRemainAmount + "  * * * ");
    }

    /**
     * * 合同基本信息 -- 增 删 改 **
     */
    private void initStatus() {
        addOrUpdate = false;
        editStatus = false;
    }

    public void add() {
        addOrUpdate = true;
        editStatus = true;
        mainInfo = new MainInformation();
        mainNumber = "";
        mainInfo.setFlowMark("0");
    }

    public void update() {
        addOrUpdate = false;
        editStatus = true;
    }

    public void delete() {
        /*
         * contract的同时 应一并上传 相应的 内容 条款 付款信息 。。。。等等
         * 不能简单处理
         */

        //ContractImpl.delContract(mainInfo.getNumber());
        initStatus();
    }

    public void checkSave() {
        if (Null.check(mainNumber)) {
            ToolKit.msgs_err("主合同编号不能为空");
            return;
        }
        if (Null.check(mainInfo.getContractTypeCode()) || mainInfo.getIsPayCon() == null) {
            ToolKit.msgs_err("请选择合同类别！");
            return;

        }
        if (1 == mainInfo.getIsPayCon()) {//1:付款合同 --> 甲方自己（手填），乙方从partner中选择
            if (Null.check(mainInfo.getPartner().getId())) {
                ToolKit.msgs_err("乙方，不能为空");
                return;
            }
            if (Null.check(mainInfo.getNameA())) {
                ToolKit.msgs_err("甲方，不能为空");
                return;
            }
            if (Null.check(mainInfo.getNameAstand())) {
                ToolKit.msgs_err("甲方法人，不能为空");
                return;
            }
        }
        if (0 == mainInfo.getIsPayCon()) {//0：收款合同 --> 乙方是自己（手填），甲方从partner中选择
            if (Null.check(mainInfo.getPartner().getId())) {
                ToolKit.msgs_err("甲方，不能为空");
                return;
            }
            if (Null.check(mainInfo.getNameA())) {
                ToolKit.msgs_err("乙方，不能为空");
                return;
            }
            if (Null.check(mainInfo.getNameAstand())) {
                ToolKit.msgs_err("乙方法人，不能为空");
                return;
            }
        }
        save();
    }

    public void save() {
        boolean ok;

        if (addOrUpdate) {
            ok = ContractImpl.insert(1, mainInfo, mainNumber);//0：主合同，1：补充合同
        } else {
            ok = ContractImpl.update(mainInfo);
        }

        if (ok) {
            initStatus();
        } else {
            ToolKit.msgs_err("数据库异常，保存失败！");
        }

        System.out.println(" * * * " + "ok " + ok + "  * * * ");
    }

    public void cancel() {
        if (addOrUpdate) {
            mainInfo = new MainInformation();
        }
        initStatus();
    }

    public void mainContractSelected(String number) {
        this.mainNumber = number;
    }

    private double getContentTotalValue() {
        double total = 0d;
        for (ContractContent row : contentModel) {
            total += (row.getCount() * row.getPrice());
        }
        return total;
    }

    private double getPayInfoTotalValue() {
        double total = 0d;
        for (PayInformation row : payInfoModel) {
            total += row.getMoney();
        }
        return total;
    }

    private boolean checkValidate() {
        if (mainInfo.getTarget().doubleValue() != getContentTotalValue()) {
            ToolKit.msgs_err("合同内容，总金额必须与标的相等");
            return false;
        }
        if (mainInfo.getTarget().doubleValue() != getPayInfoTotalValue()) {
            ToolKit.msgs_err("收付款计划，总金额必须与标的相等");
            return false;
        }
        return true;
    }

    public void submit() {
        if (!checkValidate()) return;

        int ok = ContractImpl.submit(mainInfo.getNumber());
        if (ok == 1) {
            mainInfo.setFlowMark("1");
            ToolKit.msgs_info("已提交");
        } else {
            ToolKit.msgs_err("数据库异常，操作失败");
        }
    }

    private boolean checkAble() {
        if (!CheckFlowImpl.checkFlowIsExists()) {
            /* 没有对应的审批流，则 直接跳过 视为已完成 */
            return true;
        } else {
            /* 有审批流 则必须 走完流程 并 通过 才可以 生效 */
            mainInfo = ContractImpl.queryMainInfoByNumber(mainInfo.getNumber());
            if ("99".equals(mainInfo.getFlowMark())) return true;
            else {
                ToolKit.msgs_err("合同审批中，无法生效");
                return false;
            }
        }
    }

    public void check() {
        if ("100".equals(mainInfo.getFlowMark())) return;

        if (!checkAble()) return;

        int ok = ContractImpl.check(mainInfo.getNumber());
        if (ok == 1) {
            mainInfo.setFlowMark("100");
            ToolKit.msgs_info("已生效");
        } else {
            ToolKit.msgs_err("数据库异常，操作失败");
        }
    }

    public void unCheck() {
        if ("99".equals(mainInfo.getFlowMark()) || "1".equals(mainInfo.getFlowMark())) return;

        if (!unCheckAble()) {
            ToolKit.msgs_err("合同已执行，请先删除执行信息");
            return;
        }
        int ok = ContractImpl.unCheck(mainInfo.getNumber());
        if (ok == 1) {
            if (CheckFlowImpl.checkFlowIsExists()) mainInfo.setFlowMark("99");
            else mainInfo.setFlowMark("1");
            ToolKit.msgs_info("已失效");
        } else {
            ToolKit.msgs_err("数据库异常，操作失败");
        }
    }

    private boolean unCheckAble() {
        List li = ConExecImpl.queryExecStats(mainInfo.getNumber());
        if (li == null || li.isEmpty()) return true;
        else return false;
    }

    /**
     * * 合同内容 -- 增 删 改 **
     */
    public void addLine_content() {
        List<ContractContent> templi = (ArrayList) contentModel.getWrappedData();
        if (Null.check(templi)) {
            templi = new ArrayList<ContractContent>();
        }
        ContractContent cont = new ContractContent();
        cont.setNumber(mainInfo.getNumber());
        templi.add(cont);
        contentModel.setWrappedData(templi);
    }

    public void delLine_content() {
        List<ContractContent> templi = (ArrayList) contentModel.getWrappedData();
        templi.remove(contentModel.getRowIndex());
        contentModel.setWrappedData(templi);
    }

    public void save_content() {
        ContractImpl.saveContent((ArrayList) contentModel.getWrappedData());
    }

    /**
     * * 合同条款 -- 增 删 改 **
     */
    public void addLine_item() {
        List<ContractItem> templi = (ArrayList) itemModel.getWrappedData();
        if (Null.check(templi)) {
            templi = new ArrayList<ContractItem>();
        }
        ContractItem titem = new ContractItem();
        titem.setNumber(mainInfo.getNumber());
        templi.add(titem);
        itemModel.setWrappedData(templi);
    }

    public void delLine_item() {
        List<ContractItem> templi = (ArrayList) itemModel.getWrappedData();
        templi.remove(itemModel.getRowIndex());
        itemModel.setWrappedData(templi);
    }

    public void save_item() {
        ContractImpl.saveContractItem((ArrayList) itemModel.getWrappedData());
    }

    /**
     * * 付款信息 -- 增 删 改 **
     */
    public void addLine_payInfo() {
        List<PayInformation> templi = (ArrayList) payInfoModel.getWrappedData();
        if (Null.check(templi)) {
            templi = new ArrayList<PayInformation>();
        }
        PayInformation titem = new PayInformation();
        titem.setNumber(mainInfo.getNumber());
        templi.add(titem);
        payInfoModel.setWrappedData(templi);
    }

    public void delLine_payInfo() {
        List<PayInformation> templi = (ArrayList) payInfoModel.getWrappedData();
        templi.remove(payInfoModel.getRowIndex());
        payInfoModel.setWrappedData(templi);
    }

    public void save_payInfo() {
        ContractImpl.savePayInformation((ArrayList) payInfoModel.getWrappedData());
    }

    /**
     * * 合同其他事项 -- 增 删 改 **
     */
    public void addLine_matter() {
        List<Matter> templi = (ArrayList) matterModel.getWrappedData();
        if (Null.check(templi)) {
            templi = new ArrayList<Matter>();
        }
        Matter titem = new Matter();
        titem.setNumber(mainInfo.getNumber());
        templi.add(titem);
        matterModel.setWrappedData(templi);
    }

    public void delLine_matter() {
        List<Matter> templi = (ArrayList) matterModel.getWrappedData();
        templi.remove(matterModel.getRowIndex());
        matterModel.setWrappedData(templi);
    }

    public void save_matter() {
        ContractImpl.saveMatter((ArrayList) matterModel.getWrappedData());
    }

    /**
     * * 合同违约责任 -- 增 删 改 **
     */
    public void addLine_duty() {
        List<Duty> templi = (ArrayList) dutyModel.getWrappedData();
        if (Null.check(templi)) {
            templi = new ArrayList<Duty>();
        }
        Duty titem = new Duty();
        titem.setNumber(mainInfo.getNumber());
        templi.add(titem);
        dutyModel.setWrappedData(templi);
    }

    public void delLine_duty() {
        List<Duty> templi = (ArrayList) dutyModel.getWrappedData();
        templi.remove(dutyModel.getRowIndex());
        dutyModel.setWrappedData(templi);
    }

    public void save_duty() {
        ContractImpl.saveDuty((ArrayList) dutyModel.getWrappedData());
    }

    /* * * ************************************ * * */
    public MainInformation getMainInfo() {
        return mainInfo;
    }

    public void setMainInfo(MainInformation mainInfo) {
        this.mainInfo = mainInfo;
    }

    public Integer getContentRowIndex() {
        return contentRowIndex;
    }

    public void setContentRowIndex(Integer contentRowIndex) {
        this.contentRowIndex = contentRowIndex;
    }

    public DataModel<ContractContent> getContentModel() {
        return contentModel;
    }

    public void setContentModel(DataModel<ContractContent> contentModel) {
        this.contentModel = contentModel;
    }

    public DataModel<ContractItem> getItemModel() {
        return itemModel;
    }

    public void setItemModel(DataModel<ContractItem> itemModel) {
        this.itemModel = itemModel;
    }

    public DataModel<PayInformation> getPayInfoModel() {
        return payInfoModel;
    }

    public void setPayInfoModel(DataModel<PayInformation> payInfoModel) {
        this.payInfoModel = payInfoModel;
    }

    public DataModel<Matter> getMatterModel() {
        return matterModel;
    }

    public void setMatterModel(DataModel<Matter> matterModel) {
        this.matterModel = matterModel;
    }

    public DataModel<Duty> getDutyModel() {
        return dutyModel;
    }

    public void setDutyModel(DataModel<Duty> dutyModel) {
        this.dutyModel = dutyModel;
    }

    public boolean isAddOrUpdate() {
        return addOrUpdate;
    }

    public void setAddOrUpdate(boolean addOrUpdate) {
        this.addOrUpdate = addOrUpdate;
    }

    public boolean isEditStatus() {
        return editStatus;
    }

    public void setEditStatus(boolean editStatus) {
        this.editStatus = editStatus;
    }

    public double getEnough() {
        return enough;
    }

    public void setEnough(double enough) {
        this.enough = enough;
    }

//    public DataModel<ContractType> getTypeModel() {
//        if (null == typeModel) {
//            typeModel = new ListDataModel<ContractType>();
//            initContractTypeli();
//        }
//
//        return typeModel;
//    }
//
//    public void setTypeModel(DataModel<ContractType> typeModel) {
//        this.typeModel = typeModel;
//    }
    public DataModel<Partner> getPartnerModel() {
        if (partnerModel == null) {
            partnerModel = new ListDataModel<Partner>();
            initPartnerli();
        }
        return partnerModel;
    }

    public void setPartnerModel(DataModel<Partner> partnerModel) {
        this.partnerModel = partnerModel;
    }

    public String getMainNumber() {
        return mainNumber;
    }

    public void setMainNumber(String mainNumber) {
        this.mainNumber = mainNumber;
    }

    public List<MainInformation> getMainList() {
        if (mainList == null) {
            Map map = new HashMap();
            map.put("type", 0);
            mainList = ContractImpl.queryContractList(map);
        }
        return mainList;
    }

    public void setMainList(List<MainInformation> mainList) {
        this.mainList = mainList;
    }

    public Double getDocRemainSize() {
        return docRemainSize;
    }

    public void setDocRemainSize(Double docRemainSize) {
        this.docRemainSize = docRemainSize;
    }

    public Integer getDocRemainAmount() {
        return docRemainAmount;
    }

    public void setDocRemainAmount(Integer docRemainAmount) {
        this.docRemainAmount = docRemainAmount;
    }

    public List<ContractDocument> getCurDocList() {
        return curDocList;
    }

    public void setCurDocList(List<ContractDocument> curDocList) {
        this.curDocList = curDocList;
    }
}
